package org.xiaov.core.date;

import org.xiaov.bean.date.DatePattern;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * <p>
 * Java8日期时间工具类
 * </p>
 *
 * @author: xiaovcloud
 * @date: 2021/1/17 14:50
 */

public class LocalDateHelper {
    /**
     * 日期时间字符串转换为日期时间(java.time.LocalDateTime)
     *
     * @param localDateTime 日期时间字符串
     * @param pattern       日期时间格式 例如DATETIME_PATTERN
     * @return LocalDateTime 日期时间
     */
    public static LocalDateTime parse(String localDateTime, String pattern) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDateTime.parse(localDateTime, dateTimeFormatter);
    }

    /**
     * 日期时间字符串转换为日期时间
     *
     * @param localDateTimeStr
     * @param pattern
     * @return
     */
    public static LocalDateTime parse(String localDateTimeStr, DatePattern pattern) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern.toString());
        return LocalDateTime.parse(localDateTimeStr, dateTimeFormatter);
    }

    /**
     *  日期时间字符串转换为日期时间(java.time.LocalDate)
     * @param localDateTime
     * @param pattern
     * @return
     */
    public static LocalDate parse2LocalDate(String localDateTime, String pattern) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDate.parse(localDateTime, dateTimeFormatter);
    }

    /**
     * 获取指定日期时间加上指定数量日期时间单位之后的日期时间.
     *
     * @param localDateTime 日期时间
     * @param num           数量
     * @param chronoUnit    日期时间单位
     * @return LocalDateTime 新的日期时间
     */
    public static LocalDateTime plus(LocalDateTime localDateTime, int num, ChronoUnit chronoUnit) {
        return localDateTime.plus(num, chronoUnit);
    }

    /**
     * 获取指定日期时间减去指定数量日期时间单位之后的日期时间.
     *
     * @param localDateTime 日期时间
     * @param num           数量
     * @param chronoUnit    日期时间单位
     * @return LocalDateTime 新的日期时间
     */
    public static LocalDateTime minus(LocalDateTime localDateTime, int num, ChronoUnit chronoUnit) {
        return localDateTime.minus(num, chronoUnit);
    }

    /**
     * 根据ChronoUnit计算两个日期时间之间相隔日期时间
     *
     * @param start      开始日期时间
     * @param end        结束日期时间
     * @param chronoUnit 日期时间单位
     * @return long 相隔日期时间
     */
    public static long getChronoUnitBetween(LocalDateTime start, LocalDateTime end, ChronoUnit chronoUnit) {
        return Math.abs(start.until(end, chronoUnit));
    }

    /**
     * 根据ChronoUnit计算两个日期之间相隔年数或月数或天数
     *
     * @param start      开始日期
     * @param end        结束日期
     * @param chronoUnit 日期时间单位,(ChronoUnit.YEARS,ChronoUnit.MONTHS,ChronoUnit.WEEKS,ChronoUnit.DAYS)
     * @return long 相隔年数或月数或天数
     */
    public static long getChronoUnitBetween(LocalDate start, LocalDate end, ChronoUnit chronoUnit) {
        return Math.abs(start.until(end, chronoUnit));
    }


    /**
     * 将Date转化为LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime getLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * 比较两个LocalDateTime的时间大小
     *
     * @param date
     * @param date2
     * @return
     */
    public static boolean compareTo(LocalDateTime date, LocalDateTime date2) {
        return date.isBefore(date2);
    }

    /**
     * 将LocalDateTime转化为Date
     *
     * @param localDateTime
     * @return
     */
    public static Date getDataByLocalDateTime(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 将指定格式String类型日期转化为LocalDateTime
     *
     * @param format
     * @param localDateTime
     * @return
     */
    public static LocalDateTime getLocalDateTimeByString(String format, String localDateTime) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
        return LocalDateTime.parse(localDateTime, df);
    }

    /**
     * 获取指定LocalDateTime的秒数
     *
     * @param localDateTime
     * @return
     */
    public static Long getSecondByLocalDateTime(LocalDateTime localDateTime) {
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    /**
     * 获取指定LocalDateTime的毫秒数
     *
     * @param localDateTime
     * @return
     */
    public static Long getMillSecondByLocalDateTime(LocalDateTime localDateTime) {
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * 将LocalDateTime转化为指定格式字符串
     *
     * @param localDateTime
     * @param format
     * @return
     */
    public static String getStringByLocalDateTime(LocalDateTime localDateTime, String format) {
        return localDateTime.format(DateTimeFormatter.ofPattern(format));
    }

    /**
     * 将LocalDateTime转化为默认yy-mm-dd hh:mm:ss格式字符串
     *
     * @param localDateTime
     * @return
     */
    public static String getDefaultStringByLocalDateTime(LocalDateTime localDateTime) {
        return getStringByLocalDateTime(localDateTime, DatePattern.FORMAT_LONG);
    }

    /**
     * 获取当前LocalDateTime并转化为指定格式字符串
     *
     * @param format
     * @return
     */
    public static String now(String format) {
        return getStringByLocalDateTime(LocalDateTime.now(), format);
    }

    /**
     * 获取一天的开始时间
     *
     * @param localDateTime
     * @return
     */
    public static String getStartTime(LocalDateTime localDateTime) {
        return getDefaultStringByLocalDateTime(localDateTime.with(LocalTime.MIN));
    }

    /**
     * 获取当天的开始时间
     *
     * @return
     */
    public static String getStartTime() {
        return getDefaultStringByLocalDateTime(LocalDateTime.now());
    }

    /**
     * 获取一天的结束时间
     *
     * @param localDateTime
     * @return
     */
    public static String getEndTime(LocalDateTime localDateTime) {
        return getDefaultStringByLocalDateTime(localDateTime.with(LocalTime.MAX));
    }

    /**
     * 获取当天的结束时间
     *
     * @return
     */
    public static String getEndTime() {
        return getDefaultStringByLocalDateTime(LocalDateTime.now());
    }

    /**
     * 计算两个指定格式String日期字符串的时间差(精确到毫秒)
     *
     * @param format
     * @param time1
     * @param time2
     * @return
     */
    public static Long getCompareSecondLocalDateTime(String format, String time1, String time2) {
        System.out.println("接收到的参数为:" + format + "," + time1 + "," + time2);
        LocalDateTime localDateTime1 = getLocalDateTimeByString(format, time1);
        LocalDateTime localDateTime2 = getLocalDateTimeByString(format, time2);
        if (getMillSecondByLocalDateTime(localDateTime1) > getMillSecondByLocalDateTime(localDateTime2)) {
            return getMillSecondByLocalDateTime(localDateTime1) - getMillSecondByLocalDateTime(localDateTime2);
        }
        return getMillSecondByLocalDateTime(localDateTime2) - getMillSecondByLocalDateTime(localDateTime1);
    }

    /**
     * 获取两个LocalDateTime的天数差
     *
     * @param localDateTime1
     * @param localDateTime2
     * @return
     */
    public static Long getCompareDayLocalDateTime(LocalDateTime localDateTime1, LocalDateTime localDateTime2) {
        if (compareTo(localDateTime1, localDateTime2)) {
            Duration duration = Duration.between(localDateTime1, localDateTime2);
            return duration.toDays();
        } else {
            Duration duration = Duration.between(localDateTime2, localDateTime1);
            return duration.toDays();
        }
    }

    /**
     * 获取两个LocalDateTime的小时差
     *
     * @param localDateTime1
     * @param localDateTime2
     * @return
     */
    public static Long getCompareYearLocalDateTime(LocalDateTime localDateTime1, LocalDateTime localDateTime2) {
        if (compareTo(localDateTime1, localDateTime2)) {
            Duration duration = Duration.between(localDateTime1, localDateTime2);
            return duration.toHours();
        } else {
            Duration duration = Duration.between(localDateTime2, localDateTime1);
            return duration.toHours();
        }
    }
}
